package com.hyts.serialize.binary.kryo;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.hyts.serialize.bean.KryoBean;
import com.hyts.serialize.config.SerializeConfig;
import com.hyts.serialize.factory.KryoBeanFactory;
import com.hyts.serialize.binary.BinarySerializeHandler;

/**
 * project-name:coffice-toolbox
 * package-name:com.hyts.serialize.handler
 * author:Libo/Alex
 * create-date:2019-06-21 20:55
 * copyright:libo-hyts-github
 * email:libo2dev@aliyun.com
 * description:此类主要用于: 构建kryo序列化服务对象处理器
 */
//@Builder
public class KryoSerializeHandler extends BinarySerializeHandler<KryoBean, Kryo> {

    /**
     * 线程安全
     */
    ThreadLocal<Kryo> KryoList = new ThreadLocal<Kryo>();

    /**
     *
     * @return
     */
    @Override
    public BinarySerializeHandler<KryoBean, Kryo>  build() {
        KryoList.set(KryoBeanFactory.builder().build().create());
        setResult(KryoList.get());
        return this;
    }

    /**
     *
     * @param param
     * @return
     */
    @Override
    public BinarySerializeHandler<KryoBean, Kryo> build(KryoBean param) {
        KryoList.set(KryoBeanFactory.builder().build().create(param));
        setResult(KryoList.get());
        return this;
    }

    /**
     * 序列化
     * @param value
     * @return
     */
    @Override
    public byte[] serialize(Object value) {
        if(KryoList.get() == null)
            throw new IllegalStateException("not call build function");
        byte[] output = new byte[SerializeConfig.DEFAULT_SERIALIZE_DATA_SIZE];
        try(Output outStream = new Output(output)) {
            KryoList.get().writeClassAndObject(outStream,value);
            return outStream.toBytes();
        } catch (Exception e) {
            return new byte[0];
        }
    }

    /**
     * 反序列化
     * @param param
     * @return
     */
    @Override
    public Object deserialize(byte[] param) {
        if(KryoList.get() == null)
            throw new IllegalStateException("not call build function");
        try (Input input = new Input(param)){
            return KryoList.get().readClassAndObject(input);
        } catch (Exception e) {
            return new Object();
        }
    }

    /**
     * 反序列化-强类型
     * @param byteData
     * @param clazzType
     * @param <T>
     * @return
     */
    @Override
    public <T> T deserialize(byte[] byteData, Class<T> clazzType) {
        if(KryoList.get() == null)
            throw new IllegalStateException("not call build function");
        try (Input input = new Input(byteData)){
            return KryoList.get().readObjectOrNull(input,clazzType);
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public <T> T serialize(T byteData, Class<T> clazzType) {
        throw new UnsupportedOperationException("不支持此方法-protostuff专属使用");
    }
}
